package com.datagateway.component;

import com.datagateway.component.DataLineageTracker.DataLineage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 数据血缘可视化组件
 * 负责生成数据血缘的可视化图表和报告
 * 
 * @author Data Gateway Team
 * @version 1.0.0
 */
@Component
public class DataLineageVisualizer {

    private static final Logger logger = LoggerFactory.getLogger(DataLineageVisualizer.class);

    @Autowired
    private DataLineageTracker dataLineageTracker;

    @Autowired
    private AlertManager alertManager;

    /**
     * 可视化统计信息
     */
    private final AtomicLong totalVisualizations = new AtomicLong(0);
    private final AtomicLong totalGraphs = new AtomicLong(0);
    private final AtomicLong totalReports = new AtomicLong(0);

    /**
     * 生成数据血缘图
     * 
     * @param dataId 数据ID
     * @param maxDepth 最大深度
     * @return 血缘图数据
     */
    public LineageGraph generateLineageGraph(String dataId, int maxDepth) {
        try {
            totalGraphs.incrementAndGet();
            
            // 查询上游链路
            List<DataLineage> upstreamChain = dataLineageTracker.queryDataLineageChain(dataId, maxDepth);
            
            // 查询下游影响
            List<DataLineage> downstreamImpact = dataLineageTracker.queryDataImpactAnalysis(dataId, maxDepth);
            
            // 构建节点和边
            Map<String, GraphNode> nodes = new HashMap<>();
            List<GraphEdge> edges = new ArrayList<>();
            
            // 添加当前数据节点
            GraphNode currentNode = new GraphNode(dataId, "data", "当前数据", 0, 0);
            nodes.put(dataId, currentNode);
            
            // 添加上游节点和边
            for (int i = 0; i < upstreamChain.size(); i++) {
                DataLineage lineage = upstreamChain.get(i);
                String nodeId = "upstream_" + i;
                
                GraphNode node = new GraphNode(
                    nodeId,
                    "source",
                    lineage.getSourceInfo().getSourceName(),
                    -1, i
                );
                nodes.put(nodeId, node);
                
                GraphEdge edge = new GraphEdge(
                    nodeId,
                    i == 0 ? dataId : "upstream_" + (i - 1),
                    "upstream",
                    "上游数据"
                );
                edges.add(edge);
            }
            
            // 添加下游节点和边
            for (int i = 0; i < downstreamImpact.size(); i++) {
                DataLineage lineage = downstreamImpact.get(i);
                String nodeId = "downstream_" + i;
                
                GraphNode node = new GraphNode(
                    nodeId,
                    "target",
                    lineage.getTargetInfo().getTargetName(),
                    1, i
                );
                nodes.put(nodeId, node);
                
                GraphEdge edge = new GraphEdge(
                    i == 0 ? dataId : "downstream_" + (i - 1),
                    nodeId,
                    "downstream",
                    "下游数据"
                );
                edges.add(edge);
            }
            
            LineageGraph graph = new LineageGraph(
                dataId,
                new ArrayList<>(nodes.values()),
                edges,
                upstreamChain.size(),
                downstreamImpact.size(),
                System.currentTimeMillis()
            );
            
            logger.debug("生成数据血缘图: {} -> {} 节点, {} 边", dataId, nodes.size(), edges.size());
            
            return graph;
            
        } catch (Exception e) {
            logger.error("生成数据血缘图失败: {}", dataId, e);
            alertManager.sendSystemErrorAlert("数据血缘图生成失败", e.getMessage());
            return new LineageGraph(dataId, new ArrayList<>(), new ArrayList<>(), 0, 0, System.currentTimeMillis());
        }
    }

    /**
     * 生成数据血缘报告
     * 
     * @param dataId 数据ID
     * @param maxDepth 最大深度
     * @return 血缘报告
     */
    public LineageReport generateLineageReport(String dataId, int maxDepth) {
        try {
            totalReports.incrementAndGet();
            
            // 查询血缘关系
            DataLineage lineage = dataLineageTracker.queryDataLineage(dataId);
            if (lineage == null) {
                return new LineageReport(dataId, "数据血缘关系不存在", new ArrayList<>(), new ArrayList<>(), 
                                       new ArrayList<>(), System.currentTimeMillis());
            }
            
            // 查询上游链路
            List<DataLineage> upstreamChain = dataLineageTracker.queryDataLineageChain(dataId, maxDepth);
            
            // 查询下游影响
            List<DataLineage> downstreamImpact = dataLineageTracker.queryDataImpactAnalysis(dataId, maxDepth);
            
            // 生成报告内容
            List<String> reportContent = new ArrayList<>();
            reportContent.add("数据血缘报告");
            reportContent.add("==================");
            reportContent.add("数据ID: " + dataId);
            reportContent.add("生成时间: " + new Date());
            reportContent.add("");
            
            // 当前数据信息
            reportContent.add("当前数据信息:");
            reportContent.add("- 源: " + lineage.getSourceInfo().getSourceName());
            reportContent.add("- 转换: " + lineage.getTransformationInfo().getTransformationName());
            reportContent.add("- 目标: " + lineage.getTargetInfo().getTargetName());
            reportContent.add("");
            
            // 上游链路信息
            reportContent.add("上游数据链路 (" + upstreamChain.size() + " 条):");
            for (int i = 0; i < upstreamChain.size(); i++) {
                DataLineage upstreamLineage = upstreamChain.get(i);
                reportContent.add((i + 1) + ". " + upstreamLineage.getSourceInfo().getSourceName() + 
                                " -> " + upstreamLineage.getTargetInfo().getTargetName());
            }
            reportContent.add("");
            
            // 下游影响信息
            reportContent.add("下游数据影响 (" + downstreamImpact.size() + " 条):");
            for (int i = 0; i < downstreamImpact.size(); i++) {
                DataLineage downstreamLineage = downstreamImpact.get(i);
                reportContent.add((i + 1) + ". " + downstreamLineage.getSourceInfo().getSourceName() + 
                                " -> " + downstreamLineage.getTargetInfo().getTargetName());
            }
            
            LineageReport report = new LineageReport(
                dataId,
                "数据血缘报告生成成功",
                reportContent,
                upstreamChain,
                downstreamImpact,
                System.currentTimeMillis()
            );
            
            logger.debug("生成数据血缘报告: {} -> {} 行内容", dataId, reportContent.size());
            
            return report;
            
        } catch (Exception e) {
            logger.error("生成数据血缘报告失败: {}", dataId, e);
            alertManager.sendSystemErrorAlert("数据血缘报告生成失败", e.getMessage());
            return new LineageReport(dataId, "报告生成失败: " + e.getMessage(), new ArrayList<>(), 
                                   new ArrayList<>(), new ArrayList<>(), System.currentTimeMillis());
        }
    }

    /**
     * 生成数据血缘统计图表
     * 
     * @param timeRange 时间范围（小时）
     * @return 统计图表数据
     */
    public LineageStatisticsChart generateStatisticsChart(int timeRange) {
        try {
            totalVisualizations.incrementAndGet();
            
            // 获取统计信息
            DataLineageTracker.DataLineageStatistics statistics = dataLineageTracker.getStatistics();
            
            // 生成图表数据
            List<ChartDataPoint> dataPoints = new ArrayList<>();
            
            // 模拟时间序列数据（实际项目中应该从数据库查询）
            long currentTime = System.currentTimeMillis();
            long interval = timeRange * 60 * 60 * 1000L / 24; // 24个数据点
            
            for (int i = 0; i < 24; i++) {
                long timestamp = currentTime - (23 - i) * interval;
                long value = statistics.getTotalRecords() + (long) (Math.random() * 100);
                
                dataPoints.add(new ChartDataPoint(timestamp, value));
            }
            
            LineageStatisticsChart chart = new LineageStatisticsChart(
                "数据血缘统计图表",
                "时间",
                "记录数",
                dataPoints,
                statistics,
                System.currentTimeMillis()
            );
            
            logger.debug("生成数据血缘统计图表: {} 个数据点", dataPoints.size());
            
            return chart;
            
        } catch (Exception e) {
            logger.error("生成数据血缘统计图表失败", e);
            alertManager.sendSystemErrorAlert("数据血缘统计图表生成失败", e.getMessage());
            return new LineageStatisticsChart("错误", "", "", new ArrayList<>(), null, System.currentTimeMillis());
        }
    }

    /**
     * 导出数据血缘为JSON格式
     * 
     * @param dataId 数据ID
     * @param maxDepth 最大深度
     * @return JSON格式的血缘数据
     */
    public String exportLineageToJson(String dataId, int maxDepth) {
        try {
            totalVisualizations.incrementAndGet();
            
            // 生成血缘图
            LineageGraph graph = generateLineageGraph(dataId, maxDepth);
            
            // 转换为JSON格式
            StringBuilder json = new StringBuilder();
            json.append("{\n");
            json.append("  \"dataId\": \"").append(dataId).append("\",\n");
            json.append("  \"timestamp\": ").append(System.currentTimeMillis()).append(",\n");
            json.append("  \"nodes\": [\n");
            
            for (int i = 0; i < graph.getNodes().size(); i++) {
                GraphNode node = graph.getNodes().get(i);
                json.append("    {\n");
                json.append("      \"id\": \"").append(node.getId()).append("\",\n");
                json.append("      \"type\": \"").append(node.getType()).append("\",\n");
                json.append("      \"label\": \"").append(node.getLabel()).append("\",\n");
                json.append("      \"x\": ").append(node.getX()).append(",\n");
                json.append("      \"y\": ").append(node.getY()).append("\n");
                json.append("    }");
                if (i < graph.getNodes().size() - 1) {
                    json.append(",");
                }
                json.append("\n");
            }
            
            json.append("  ],\n");
            json.append("  \"edges\": [\n");
            
            for (int i = 0; i < graph.getEdges().size(); i++) {
                GraphEdge edge = graph.getEdges().get(i);
                json.append("    {\n");
                json.append("      \"source\": \"").append(edge.getSource()).append("\",\n");
                json.append("      \"target\": \"").append(edge.getTarget()).append("\",\n");
                json.append("      \"type\": \"").append(edge.getType()).append("\",\n");
                json.append("      \"label\": \"").append(edge.getLabel()).append("\"\n");
                json.append("    }");
                if (i < graph.getEdges().size() - 1) {
                    json.append(",");
                }
                json.append("\n");
            }
            
            json.append("  ]\n");
            json.append("}\n");
            
            logger.debug("导出数据血缘为JSON: {} -> {} 字符", dataId, json.length());
            
            return json.toString();
            
        } catch (Exception e) {
            logger.error("导出数据血缘为JSON失败: {}", dataId, e);
            return "{\"error\": \"" + e.getMessage() + "\"}";
        }
    }

    /**
     * 获取可视化统计信息
     * 
     * @return 统计信息
     */
    public VisualizationStatistics getStatistics() {
        return new VisualizationStatistics(
            totalVisualizations.get(),
            totalGraphs.get(),
            totalReports.get(),
            System.currentTimeMillis()
        );
    }

    /**
     * 图节点类
     */
    public static class GraphNode {
        private final String id;
        private final String type;
        private final String label;
        private final int x;
        private final int y;

        public GraphNode(String id, String type, String label, int x, int y) {
            this.id = id;
            this.type = type;
            this.label = label;
            this.x = x;
            this.y = y;
        }

        // Getter方法
        public String getId() { return id; }
        public String getType() { return type; }
        public String getLabel() { return label; }
        public int getX() { return x; }
        public int getY() { return y; }
    }

    /**
     * 图边类
     */
    public static class GraphEdge {
        private final String source;
        private final String target;
        private final String type;
        private final String label;

        public GraphEdge(String source, String target, String type, String label) {
            this.source = source;
            this.target = target;
            this.type = type;
            this.label = label;
        }

        // Getter方法
        public String getSource() { return source; }
        public String getTarget() { return target; }
        public String getType() { return type; }
        public String getLabel() { return label; }
    }

    /**
     * 血缘图类
     */
    public static class LineageGraph {
        private final String dataId;
        private final List<GraphNode> nodes;
        private final List<GraphEdge> edges;
        private final int upstreamCount;
        private final int downstreamCount;
        private final long timestamp;

        public LineageGraph(String dataId, List<GraphNode> nodes, List<GraphEdge> edges,
                          int upstreamCount, int downstreamCount, long timestamp) {
            this.dataId = dataId;
            this.nodes = nodes;
            this.edges = edges;
            this.upstreamCount = upstreamCount;
            this.downstreamCount = downstreamCount;
            this.timestamp = timestamp;
        }

        // Getter方法
        public String getDataId() { return dataId; }
        public List<GraphNode> getNodes() { return nodes; }
        public List<GraphEdge> getEdges() { return edges; }
        public int getUpstreamCount() { return upstreamCount; }
        public int getDownstreamCount() { return downstreamCount; }
        public long getTimestamp() { return timestamp; }
    }

    /**
     * 血缘报告类
     */
    public static class LineageReport {
        private final String dataId;
        private final String status;
        private final List<String> content;
        private final List<DataLineage> upstreamChain;
        private final List<DataLineage> downstreamImpact;
        private final long timestamp;

        public LineageReport(String dataId, String status, List<String> content,
                           List<DataLineage> upstreamChain, List<DataLineage> downstreamImpact, long timestamp) {
            this.dataId = dataId;
            this.status = status;
            this.content = content;
            this.upstreamChain = upstreamChain;
            this.downstreamImpact = downstreamImpact;
            this.timestamp = timestamp;
        }

        // Getter方法
        public String getDataId() { return dataId; }
        public String getStatus() { return status; }
        public List<String> getContent() { return content; }
        public List<DataLineage> getUpstreamChain() { return upstreamChain; }
        public List<DataLineage> getDownstreamImpact() { return downstreamImpact; }
        public long getTimestamp() { return timestamp; }
    }

    /**
     * 图表数据点类
     */
    public static class ChartDataPoint {
        private final long timestamp;
        private final long value;

        public ChartDataPoint(long timestamp, long value) {
            this.timestamp = timestamp;
            this.value = value;
        }

        // Getter方法
        public long getTimestamp() { return timestamp; }
        public long getValue() { return value; }
    }

    /**
     * 血缘统计图表类
     */
    public static class LineageStatisticsChart {
        private final String title;
        private final String xAxisLabel;
        private final String yAxisLabel;
        private final List<ChartDataPoint> dataPoints;
        private final DataLineageTracker.DataLineageStatistics statistics;
        private final long timestamp;

        public LineageStatisticsChart(String title, String xAxisLabel, String yAxisLabel,
                                    List<ChartDataPoint> dataPoints, DataLineageTracker.DataLineageStatistics statistics,
                                    long timestamp) {
            this.title = title;
            this.xAxisLabel = xAxisLabel;
            this.yAxisLabel = yAxisLabel;
            this.dataPoints = dataPoints;
            this.statistics = statistics;
            this.timestamp = timestamp;
        }

        // Getter方法
        public String getTitle() { return title; }
        public String getXAxisLabel() { return xAxisLabel; }
        public String getYAxisLabel() { return yAxisLabel; }
        public List<ChartDataPoint> getDataPoints() { return dataPoints; }
        public DataLineageTracker.DataLineageStatistics getStatistics() { return statistics; }
        public long getTimestamp() { return timestamp; }
    }

    /**
     * 可视化统计信息类
     */
    public static class VisualizationStatistics {
        private final long totalVisualizations;
        private final long totalGraphs;
        private final long totalReports;
        private final long timestamp;

        public VisualizationStatistics(long totalVisualizations, long totalGraphs, long totalReports, long timestamp) {
            this.totalVisualizations = totalVisualizations;
            this.totalGraphs = totalGraphs;
            this.totalReports = totalReports;
            this.timestamp = timestamp;
        }

        // Getter方法
        public long getTotalVisualizations() { return totalVisualizations; }
        public long getTotalGraphs() { return totalGraphs; }
        public long getTotalReports() { return totalReports; }
        public long getTimestamp() { return timestamp; }
    }
}
